package view.Windows;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.eclipse.swt.*;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.Font;
import org.eclipse.swt.graphics.FontData;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.widgets.*;

import view.Tabs.HomePageGUI;

import commons.Entities.User;
import commons.Exceptions.userDoesntExistException;
import commons.Exceptions.wrongPasswordException;

import controller.ControllerFunctions;

public final class LoginGUI {

	private static final Log logger = LogFactory.getLog(LoginGUI.class);
	private final static LoginGUI INSTANCE = new LoginGUI();

	public static LoginGUI get() {
		return INSTANCE;
	}
	
	public LoginGUI() {
	}

	// final public Shell shlMain;
	protected Color cBackgroundColor;
	protected Font fHeadFont;
	protected Font fLabelFont;
	protected Font fButtonFont;
	protected Display mainDisp;

	/**
	 * constructor
	 * 
	 * @param mainDisp
	 */
	public void LoginGUIRun(final Display mainDisp, final Shell shlMain) {

		setMainDisp(mainDisp);
		initFonts(mainDisp);

		Image icon = new Image(mainDisp, getClass().getClassLoader().getResourceAsStream("view/Assets/LegenDate.png"));
		shlMain.setImage(icon);
		shlMain.setBounds(10, 10, 900, 700);

		// locate the shell in the center of the display
		Monitor primary = mainDisp.getPrimaryMonitor();
		Rectangle bounds = primary.getBounds();
		Rectangle rect = shlMain.getBounds();
		int x = bounds.x + (bounds.width - rect.width) / 2;
		int y = bounds.y + (bounds.height - rect.height) / 2;
		shlMain.setLocation(x, y);

		// main definitions
		shlMain.setText("LegenDate - Login");
		setBackgroundColor(new Color(mainDisp, 240, 240, 240));
		Image imgBackground = new Image(mainDisp, getClass().getClassLoader().getResourceAsStream("view/Assets/LegenDateBG.jpg"));
		shlMain.setBackgroundImage(imgBackground);
		shlMain.setBackgroundMode(SWT.INHERIT_DEFAULT);

		Group grLogin = new Group(shlMain, SWT.NO_BACKGROUND);
		grLogin.setBounds(300, 220, 300, 170);
		Color clrWhite = new Color(mainDisp, 255, 255, 255);

		// user name
		Label lblUser = new Label(grLogin, 0);
		lblUser.setText("UserName: ");
		lblUser.setBounds(25, 30, 85, 20);
		lblUser.setForeground(clrWhite);
		lblUser.setFont(getLabelFont());

		final Text txUser = new Text(grLogin, SWT.BORDER);
		txUser.setBounds(115, 30, 160, 20);

		// password
		Label lblPassword = new Label(grLogin, 0);
		lblPassword.setText("Password: ");
		lblPassword.setBounds(25, 70, 85, 20);
		lblPassword.setForeground(clrWhite);
		lblPassword.setFont(getLabelFont());

		final Text txPassword = new Text(grLogin, SWT.BORDER | SWT.PASSWORD);
		txPassword.setBounds(115, 70, 160, 20);

		// login button
		Button btnLogin = new Button(grLogin, SWT.NONE);
		btnLogin.setFont(getButtonFont());
		btnLogin.setText("Login");
		btnLogin.setBounds(100, 120, 100, 30);
		btnLogin.addSelectionListener(new SelectionAdapter() {

			@Override
			public void widgetSelected(SelectionEvent e) {
				User currentUser;
				try {
					currentUser = ControllerFunctions.get().login(txUser.getText(), txPassword.getText());
				} catch (userDoesntExistException e1) {
					logger.info(e1);
					ErrorMessageGUI errorMsg = new ErrorMessageGUI(mainDisp, e1.toString());
					errorMsg.showGUI(mainDisp);
					return;
				} catch (wrongPasswordException e1) {
					logger.info(e1);
					ErrorMessageGUI errorMsg = new ErrorMessageGUI(mainDisp, e1.toString());
					errorMsg.showGUI(mainDisp);
					return;
				}

				shlMain.close();
				HomePageGUI.get().HomePageGUIRun(mainDisp, currentUser.getUserName());
				HomePageGUI.get().showGUI(mainDisp);
				shlMain.dispose();
			}
		});

		// login when pressing 'enter'
		shlMain.addListener(SWT.Traverse, new Listener() {

			public void handleEvent(Event event) {
				switch (event.detail) {
					case SWT.TRAVERSE_RETURN:
						User currentUser;
						try {
							currentUser = ControllerFunctions.get().login(txUser.getText(), txPassword.getText());
						} catch (userDoesntExistException e1) {
							logger.info(e1);
							ErrorMessageGUI errorMsg = new ErrorMessageGUI(mainDisp, e1.toString());
							errorMsg.showGUI(mainDisp);
							return;
						} catch (wrongPasswordException e1) {
							logger.info(e1);
							ErrorMessageGUI errorMsg = new ErrorMessageGUI(mainDisp, e1.toString());
							errorMsg.showGUI(mainDisp);
							return;
						}

						shlMain.close();
						HomePageGUI.get().HomePageGUIRun(mainDisp, currentUser.getUserName());
						HomePageGUI.get().showGUI(mainDisp);
						shlMain.dispose();
				}
			}
		});

		// register button
		Group grRegister = new Group(shlMain, 0);
		grRegister.setBounds(300, 405, 300, 50);

		Label lblNewToLegenDate = new Label(grRegister, 0);
		lblNewToLegenDate.setText("New to LegenDate?");
		lblNewToLegenDate.setBounds(20, 20, 160, 20);
		lblNewToLegenDate.setFont(getLabelFont());
		lblNewToLegenDate.setForeground(clrWhite);

		Button btnRegister = new Button(grRegister, SWT.NONE);
		btnRegister.setFont(getButtonFont());
		btnRegister.setText("Register");
		btnRegister.setBounds(180, 15, 100, 30);
		btnRegister.addSelectionListener(new SelectionAdapter() {

			@Override
			public void widgetSelected(SelectionEvent e) {
				shlMain.close();
				new RegisterGUI(mainDisp).showGUI(mainDisp);
				shlMain.dispose();
			}
		});

		// update DB from FreeBase button
		Button btnUpdateDB = new Button(shlMain, SWT.NONE);
		btnUpdateDB.setFont(getButtonFont());
		btnUpdateDB.setText("Update DB");
		btnUpdateDB.setBounds(380, 480, 140, 30);
		btnUpdateDB.addSelectionListener(new SelectionAdapter() {

			@Override
			public void widgetSelected(SelectionEvent e) {
				ControllerFunctions.get().updateDBFromFreebase();
				UpdateDBGUI.get().UpdateDBGUIRun(mainDisp);
			}
		});

		shlMain.open();
		// this is what's holding the shell open!!!
		while (!shlMain.isDisposed()) {
			if (!mainDisp.readAndDispatch())
				mainDisp.sleep();
		}		
	}

	public Color getBackgroundColor() {
		return cBackgroundColor;
	}

	public void setBackgroundColor(Color cBackgroundColor) {
		this.cBackgroundColor = cBackgroundColor;
	}

	public Font getHeadFont() {
		return fHeadFont;
	}

	public void setHeadFont(Font fHeadFont) {
		this.fHeadFont = fHeadFont;
	}

	public Font getLabelFont() {
		return fLabelFont;
	}

	public void setLabelFont(Font fLabelFont) {
		this.fLabelFont = fLabelFont;
	}

	public Font getButtonFont() {
		return fButtonFont;
	}

	public void setButtonFont(Font fButtonFont) {
		this.fButtonFont = fButtonFont;
	}

	
	public Display getMainDisp() {
		return mainDisp;
	}

	
	public void setMainDisp(Display mainDisp) {
		this.mainDisp = mainDisp;
	}

	/**
	 * initialize fonts
	 * 
	 * @param display
	 */
	protected void initFonts(Display display) {
		setHeadFont(new Font(display, new FontData("Fiolex Girls", 20, SWT.BOLD)));
		setLabelFont(new Font(display, new FontData("Ariel", 10, SWT.BOLD)));
		setButtonFont(new Font(display, new FontData("Ariel", 10, SWT.BOLD)));

	}
}
